`
https://leetcode.cn/problems/minimum-number-of-seconds-to-make-mountain-height-zero/
`

/**
 * @param {number} mountainHeight
 * @param {number[]} workerTimes
 * @return {number}
 */
var minNumberOfSeconds = function (mountainHeight, workerTimes) {
  // t 时刻能挖掉多少高度的山
  const f = (t) => {
    // 下式可通过解方程，对于每个工人 wt[i] 至多花费 t 可以挖掉多少高度的山 m * (m + 1) / 2 * wt[i] = t 解得
    return workerTimes.reduce((acc, cur) => acc + Math.floor((-1 + Math.sqrt(1 + 8 * Math.floor(t / cur))) / 2), 0)
  }
  // 找到两个循环不变量
  const minT = Math.min(...workerTimes)
  // 挖得最快的还没挖掉第一个高度，此时不可能挖完
  let left = minT - 1
  // 挖得最快的自己挖掉了所有的高度，此时肯定挖完
  let right = minT * mountainHeight * (mountainHeight + 1) / 2
  while (left + 1 < right) {
    const mid = left + Math.floor((right - left) / 2)
    // 找第一个挖掉高度 >= mountainHeight 的时刻
    if (f(mid) < mountainHeight) {
      left = mid
    } else {
      right = mid
    }
  }
  return right
};